using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using STD.Shared.Common.Enums;
using MySql.Data.MySqlClient;

namespace STD.Shared.Infrastructure.Database.Providers;

/// <summary>
/// MySQL数据库提供者
/// </summary>
public class MySQLProvider : IDatabaseProvider
{
    /// <summary>
    /// 数据库类型
    /// </summary>
    public DatabaseType DatabaseType => DatabaseType.MySQL;
    
    /// <summary>
    /// 配置DbContext
    /// </summary>
    /// <param name="optionsBuilder">DbContext选项构建器</param>
    /// <param name="connectionString">连接字符串</param>
    public void ConfigureDbContext(DbContextOptionsBuilder optionsBuilder, string connectionString)
    {
        optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), options =>
        {
            options.EnableRetryOnFailure(3, TimeSpan.FromSeconds(30), null);
        });
    }
    
    /// <summary>
    /// 获取连接字符串
    /// </summary>
    /// <param name="configuration">配置</param>
    /// <param name="sectionName">配置节名称</param>
    /// <returns>连接字符串</returns>
    public string GetConnectionString(IConfiguration configuration, string sectionName)
    {
        var server = configuration.GetValue<string>($"{sectionName}:Server") ?? "localhost";
        var port = configuration.GetValue<int>($"{sectionName}:Port", 3306);
        var database = configuration.GetValue<string>($"{sectionName}:Database") ?? "mysql";
        var username = configuration.GetValue<string>($"{sectionName}:Username") ?? "root";
        var password = configuration.GetValue<string>($"{sectionName}:Password") ?? "password";
        
        return $"Server={server};Port={port};Database={database};Uid={username};Pwd={password};";
    }
    
    /// <summary>
    /// 验证连接
    /// </summary>
    /// <param name="connectionString">连接字符串</param>
    /// <returns>是否连接成功</returns>
    public async Task<bool> ValidateConnectionAsync(string connectionString)
    {
        try
        {
            using var connection = new MySqlConnection(connectionString);
            await connection.OpenAsync();
            return true;
        }
        catch
        {
            return false;
        }
    }
} 